/* 
在变量中存储状态=》这些变量存放在哪里？=》作用域

javascript是一门编译型语言：

编译过程：
词法分析=》解析（生成ast树）=》机器代码生成（根据ast树生成可以执行的代码）

javascript的编译是在运行之前进行，仅仅是运行前的几毫米进行，然后紧接着开始运行

引擎：执行代码
编译器：对代码进行编译
作用域：保存变量，同时制定出变量获取规则

javascript的编译过程（`var a = 2`）：
1、Encountering var a, Compiler asks Scope to see if a variable a already exists for that particular scope collection. If so, Compiler ignores this declaration and moves on. Otherwise, Compiler asks Scope to declare a new variable called a for that scope collection.
2、Compiler then produces code for Engine to later execute, to handle the a = 2 assignment. The code Engine runs will first ask Scope if there is a variable called a accessible in the current scope collection. If so, Engine uses that variable. If not, Engine looks elsewhere (see nested Scope section below).
简单说就是：编译器声明变量（如果当前作用域之前没有声明过），在运行的时候，引擎在作用域中寻找这个变量，如果找到就赋值


两种搜索：
LHS：寻找变量的地址，用来进行赋值
RHS：所有的非lhs操作，目的是用来获取值

引擎在运行的时候会去向作用域请求相应的变量用于执行。

*/

function foo(a) {//lhs,2 assigned to a
	console.log( a ); // 2
}
foo( 2 );//rhs

/* 
作用域嵌套：
如果在当前作用域中找不到需要的变量，则会到外层去寻找，直至找到需要的变量或者是到全局作用域
*/

/* 
报错
*/
function foo1(a) {
	// console.log( a + b );//b:undecleard(ReferenceError)变量没有定义时进行rhs搜索
    b = a;//如果在非严格模式下，lhs没有找到对应的变量，会在global中创建一个变量
    console.log(window.b);
    a.d();//如果rls成功找到了变量，但是调用变量上一个非法的字段，会报TypeError错误
}
foo1( 2 );